--- 战斗主类
---
--- @class FighterManager
FighterManager = ClientFight.CreateClass("FighterManager")
local this = FighterManager

--- @public
--- @return FighterManager
function FighterManager:ctor()

end
--[[
* 死亡事件
*
* @param fighter
]]
function this.die(fight, fighter, killer, dieType)
    if (fighter.dieStatus) then
        return ;
    end
    fighter.hp = 0;
    fighter:incrementDieTimes();
    fighter.dieStatus = true;
    local frameInfoCommand = ReportManager.dieToJsonString(fight, fighter, dieType, killer);
    table.insert(fight.actions, frameInfoCommand)
    FightManager.playActions(frameInfoCommand)
    if (fighter.puppet ~= nil and not fighter.summons) then
        --            fight.actions.add(ReportManager.dieToJsonString(fight, fighter.puppet, dieType,killer));
    end
    SkillRoleMgr.savePathFile("[" .. fight.frame .. "][DIE]" .. fighter.fighterId .. "死亡");
    if (fighter.usingSkill ~= nil) then
        ClientFight.SkillClientManager.finishSkill(fighter.usingSkill, true, FinishSkillReasonEnum.ATTACKER_DIE);
    end

    this.onKillSomeOne(fight, killer, fighter, dieType);
    if (fighter.summons) then
        for i, v in pairs(fight.teams[fighter.teamIndex].fighters) do
            if v.fighterId == fight.fighterId then
                fight.teams[fighter.teamIndex].fighters[i] = nil;
            end
            return ;
        end
    end

    SkillRoleMgr.savePathFile(string.format("[%s][DIE]%s死亡在%s帧时触发延时逻辑",
            fight.frame, fighter.fighterId, fight.frame + Global.FIGHTER_DIE_TIME
    ));
    local teamIndex = fighter.teamIndex;
    local site = fighter.site;
    this.alternateReady(fight, teamIndex, site, Global.FIGHTER_DIE_TIME);

    -- 检查战斗结束
    this.checkFinish(fight);

end
--[[
* 支援位英雄准备入场
* @param fight
* @param teamIndex
* @param site
]]
function this.alternateReady(fight, teamIndex, site, delayFrame)
    ClientFight.EventManager.addDelayedEvent(fight, fight.frame + delayFrame, function()
        local alternate = this.alternateEnterScene(fight, teamIndex, site);
        if (alternate == nil) then
            ClientFight.SkillClientManager.useSupportSkill(fight, teamIndex);
        else
            ClientFight.EventManager.addDelayedEvent(fight, fight.frame + 5, function()
                ClientFight.SkillClientManager.useSupportSkill(fight, teamIndex);
            end);
        end
    end);
end

--[[
*
* @param fight
* @param killer 杀手
* @param dier 被杀的
* @param dieType
]]
function this.onKillSomeOne(fight, killer, dier, dieType)
    -- 增加能量，召唤物消失的时候killer为nil
    if (killer ~= nil and not dier.summons) then
        if not (killer.summons) then
            addEnergy(fight, killer, 0, 0, Global.DIE_RECOVER_ENERGY, EnergyChangeReasonEnum.KILL);
        elseif killer.summonsType == SummonsType.UN_ENTITY then
            local creater = killer.summonsCreater;
            if (creater ~= nil) then
                addEnergy(fight, creater, 0, 0, Global.DIE_RECOVER_ENERGY, EnergyChangeReasonEnum.KILL);
            end
        else
            addEnergy(fight, killer, 0, 0, Global.DIE_RECOVER_ENERGY, EnergyChangeReasonEnum.KILL);
        end
    end
    if (dieType == FighterDieType.NORMAL) then
        --正常击杀, 清掉击杀者的普攻CD
        if (killer ~= nil) then
            local normalAttack = killer.normalAttack;
            if (normalAttack ~= nil) then
                ClientFight.SkillClientManager.cleanCooldown(killer, normalAttack.skillId);
            end
        end
        if (not dier.summons) then
            if (dier == killer or killer == nil) then
                if (dier.lastDamageMe ~= 0) then
                    local fighter = fight.getFighter(dier.lastDamageMe);
                    if (fighter ~= nil) then
                        fighter.fighterStats:addKillNum(1);
                    end
                end
            else
                killer.fighterStats:addKillNum(1);
            end
        end
    end
end
--
--[[
* 复活
*
* @param fight    战斗
* @param fighter  战士
* @param reviveHp 恢复血量
]]
function this.revive(fight, fighter, source, reviveHp)
    DamageManager.setFighterHp(fight, fighter, source, nil, DamageResultTypeEnum.HEAL, reviveHp, reviveHp, true, false, true);
    fighter.dieStatus = false;
    local frameInfoCommand = ReportManager.reviveToJsonString(fight, fighter);
    table.insert(fight.actions, frameInfoCommand)
    FightManager.playActions(frameInfoCommand)
end

--[[
* 替补加入集合n帧后入场
* @param fight
* @param teamIndex 队伍
* @param teamIndex 队伍
* @param Site 站位
]]
function this.alternateEnterScene(fight, teamIndex, Site)
    -- 替补登场
    local team = fight.teams[teamIndex];
    if table.getn(team.alternates) > 0 then
        local _fighter = table.remove(team.alternates, 1);
        -- 初始化站位
        local alternatePos = FighterUtils.randomAlternatePos(teamIndex);
        _fighter.position = Vector2.New(alternatePos.x, alternatePos.y);
        -- 继承死亡者的位置和阵法
        _fighter.site = Site;
        SkillRoleMgr.savePathFile(string.format("[%s][FIGHT]替补%s准备入场%s,x=%s,y=%s",
                fight.frame, _fighter.fighterId, _fighter:printAttr(), alternatePos.x, alternatePos.y
        ));
        -- 入场
        fighterEnterScene(fight, _fighter, nil, 0);
        return _fighter;
    end
    return nil;
end

function this.beforeEnterScene(fighter)
    local puppet = fighter.puppet;
    if (puppet == nil or fighter.summons) then
        return ;
    end
    puppet.position = fighter.position;

    local base = puppet.position;
    local teamSiteDirection = FighterUtils.getTeamSiteDirection(fighter);
    local vector2 = new
    Vector2(base.x + teamSiteDirection * 1, base.y);

    fighter.setPosition(vector2);
    --        fighter.setInitPosition(new Vector2(fighter.position));
end


--[[
* 战斗中入场
* @param type 0:替补入场  1:召唤物入场
]]
function this.fighterEnterScene(fight, fighter, skill, type)
    local team = fight.teams[fighter.teamIndex];
    table.insert(team.fighters, fighter);
    beforeEnterScene(fighter);
    -- 需要先写 入场战报, 才能开始给自己加buff什么的
    if type == 0 then
        local frameInfoCommand = {};
        if (fighter.puppet ~= nil) then
            addPassiveSkillEffect(fight, fighter.puppet);
            frameInfoCommand = ReportManager.enterSceneToJsonString(fight, fighter.puppet);
            table.insert(fight.actions, frameInfoCommand)
            FightManager.playActions(frameInfoCommand)
        end
        frameInfoCommand = ReportManager.enterSceneToJsonString(fight, fighter);
        table.insert(fight.actions, frameInfoCommand);
        FightManager.playActions(frameInfoCommand)


    elseif type == 1 then
        local frameInfoCommand = ReportManager.summonToJsonString(fight, fighter);
        table.insert(fight.actions, frameInfoCommand);
        FightManager.playActions(frameInfoCommand)
    end

    addPassiveSkillEffect(fight, fighter);
    for i = 1, table.getn(fight.teams) do
        local fighters = fight.teams[i].fighters;
        for i, __fighter in pairs(fighters) do
            if not __fighter:isDie() then
                addInitFightPassiveSkillEffect(fight, __fighter);
            end
        end
    end

    if type == 0 then
        local frozenSkill = ClientFight.SkillClientManager.createFightSkill(fight, FightConst.ALTERNATE_ENTER_SCENE_FROZEN_SKILL, nil);
        ClientFight.SkillClientManager.useSkill(fight, fighter, fighter, frozenSkill);
        SkillRoleMgr.savePathFile(string.format("[%s]替补%s登场释放子弹时间技能",
                fight.frame, fighter.fighterId
        ));
    elseif type == 1 then
        if (skill ~= nil) then
            local skillEffect = ClientFight.SkillClientManager.getSkillEffect(skill.skill.skillBean.f_SkillScript);
            if (skillEffect ~= nil) then
                skillEffect:summonEnterSceneAfter(skill, fighter);
            end
        end

    end
    --检测主动类光环,套自己身上
    for i = 1, table.getn(fight.teams) do
        local fighters = clone(fight.teams[i].fighters);
        for i1, other in pairs(fighters) do
            if not other:isDie() then
                local activHaloBuff = other.activHaloBuff;
                if table.getn(activHaloBuff) <= 0 then
                    goto continue1;
                end
                for i2, fighterBuff in pairs(activHaloBuff) do

                    local skillBean = fighterBuff.skill.skill.skillBean;
                    if (SkillTargetTypeEnum.TARGET == skillBean.f_Target) then
                        if (other.teamIndex == fighter.teamIndex) then
                            goto continue;
                        end
                    else
                        if (other.teamIndex ~= fighter.teamIndex) then
                            goto continue;
                        end
                    end
                    :: continue ::

                    ClientFight.BuffManager.addBuff(fight, fighterBuff.skill, other, fighter, false, fighterBuff.modelId, fighterBuff.overlay, fighterBuff.addParameters);
                end
                ::continue1::
            end
        end
    end
    if (type == 1) then
        local triggerList = FighterUtils.getFightersBy(fight, nil, true, nil);
        for i, trigger in pairs(triggerList) do

            ClientFight.EventManager.notifyEventListener(fight, FightEventEnum.summonEnterSceneAfter, trigger.fighterId, fighter.summonsCreater);
        end
    end
end

--[[
* 创建召唤物
* 默认位置 {0,0}
* @param fight
* @param parent    召唤者
* @param aiType    {@link FighterAiTypeEnum}
* @param attr 继承属性百分比 [[属性id,百分比],[属性id,百分比]....]
     * @param lifetime 存活时间 -1为永久
     * @return
     * @throws BehaviourTreeNonActionOrConditionException
     ]]
function this.createSummonsFighter(fight, parent, modelId, aiType, summonsType, attr, lifetime)
    local heroBean = DataManager.t_heroBeanMap[modelId];
    if (heroBean == nil) then
    end

    local fighter = Fighter.New();
    fighter.fight = fight;
    fighter.fightTeam = parent.fightTeam;
    fighter.teamIndex = parent.teamIndex;
    fighter.fighterId = fight.ids
    fight.ids = fight.ids + 1
    fighter.leader = false;

    -- 模型ID
    fighter.modelId = modelId;
    fighter.star =parent.star;
    fighter.level = parent.level;
    fighter.position = Vector2.New(parent.position.x, parent.position.y);
    fighter.weaponLevel = parent.weaponLevel;

    -- BUFF属性不克隆
    local excludes = {};
    table.insert(excludes, CalculatorTypeEnum.BUFF);
    -- 英雄配置
    fighter.heroBean = heroBean;
    -- 体型
    fighter.shape = Rectangle2.New(fighter.heroBean.f_HeroSize);
    -- 警戒范围1
    if (fighter.heroBean.f_WarningRange1 ~= nil) then
        fighter.alertRange1 = Rectangle2.New(fighter.heroBean.f_WarningRange1);
    end
    -- 警戒范围2
    if (fighter.heroBean.f_WarningRange2 ~= nil) then
        fighter.alertRange2 = Rectangle2.New(fighter.heroBean.f_WarningRange2);
    end

    --召唤物相关
    fighter.summons = true;
    fighter.summonsType = summonsType;
    fighter.summonsCreater = parent;
    fighter.summonsCreateFrame = fight.frame;
    fighter.skillDynamic = parent.skillDynamic;
    fighter.skillDynamicParam = parent.skillDynamicParam;
    fighter.buffDynamicParam = parent.buffDynamicParam;
    if (lifetime > 0) then
        local expireFrame = lifetime / Global.FIGHT_FRAME;
    fighter.summonsExpireFrame = fight.frame + expireFrame;
        fighter.lifeFrame = expireFrame;
    end

    if (summonsType == SummonsType.UN_ENTITY) then
        FighterAttributeManager.cloneAllAttr(parent, fighter, excludes);
    else
        --继承属性
        if (attr ~= nil) then
            FighterAttributeManager.cloneAllAttr(parent, fighter, excludes, attr);
        end
    end

    FighterAttributeManager.initFighterAttribute(fight, fighter);

    --以下为初始化逻辑

    -- 初始开始血量
    fighter.hp = FighterAttributeManager.getFightAttr(fighter, FighterAttributeEnum.HP);

    -- 初始化普通攻击
    local normalSkillId = fighter.heroBean.f_HeroAtk;
    if (normalSkillId > 0) then
        fighter.normalAttack = ClientFight.SkillClientManager.createFightSkill(fight, normalSkillId, fighter);
    end

    local skills = {};

    -- 技能
    local skillUnlockBean1 = DataManager.getSkillUnlockBean(fighter.modelId, fighter.level, fighter.star, 1);
    if (skillUnlockBean1 ~= nil) then
        table.insert(skills, skillUnlockBean1);
    end
    local skillUnlockBean2 = DataManager.getSkillUnlockBean(fighter.modelId, fighter.level, fighter.star, 2);
    if (skillUnlockBean2 ~= nil) then
        table.insert(skills, skillUnlockBean2);
    end
    local skillUnlockBean3 = DataManager.getSkillUnlockBean(fighter.modelId, fighter.level, fighter.star, 3);
    if (skillUnlockBean3 ~= nil) then
        table.insert(skills, skillUnlockBean3);
    end
    local skillUnlockBean4 = DataManager.getSkillUnlockBean(fighter.modelId, fighter.level, fighter.star, 4);
    if (skillUnlockBean4 ~= nil) then
        table.insert(skills, skillUnlockBean4);
    end


    -- 初始化可以使用技能
    local maxEnergy = 0;
    for i, skillBean in pairs(skills) do

        local skill = ClientFight.SkillClientManager.addSkill(fight, fighter, skillBean.skillId, skillBean.skillType);
        if (skill ~= nil) then
            local energy = skill.skillBean.f_UseSP;
            if (energy > maxEnergy) then
                maxEnergy = energy;
            end
        end
    end

    -- 排序
    table.sort(fighter.skills,function(o1, o2)
        if (o1.skillBean.f_SkillPriority > o2.skillBean.f_SkillPriority) then
            return -1;
        elseif (o1.skillBean.f_SkillPriority < o2.skillBean.f_SkillPriority) then
            return 1;
        end
        return 0;
    end);

    fighter.maxEnergy = maxEnergy;

    local aiTypeEnum = FighterAiConstans.getAiTypeEnum(aiType);
    local aiJson = FighterAiConstans.getAiJsonByType(aiTypeEnum);
    --构建行为树
    fighter.aiTree =  ClientFight.BehaviourTreesBuilder:build(fight, fighter, aiJson);
    fighter.summonId = modelId;
    return fighter;
end

--[[
 * 召唤物过期
 * @param fight
 * @param summon
 ]]
function this.checkSummonTime(fight, summon)
    if (summon.summonsExpireFrame < 0) then
        return ;
    end
    if (fight.frame < summon.summonsExpireFrame) then
        return ;
    end
    SkillRoleMgr.savePathFile(string.format("[%s]%s的召唤物%s到达过期时间",
            fight.frame, summon.summonsCreater.fighterId, summon.fighterId
    ));

    ClientFight.EventManager.notifyEventListener(fight, FightEventEnum.SUMMON_EXPIRE_BEFORE, summon.fighterId, summon);
    FighterManager.die(fight, summon, nil, FighterDieType.SUMMON_EXPIRE);
    ClientFight.EventManager.notifyEventListener(fight, FightEventEnum.SUMMON_EXPIRE_AFTER, summon.fighterId, summon);
    local ours = FighterUtils.getOursBy(summon, true, nil);

    --        FightUsingSkill skill = new FightUsingSkill();
    --        skill.setFight(fight);
    --        skill.setFighter(summon);
    --        skill.setTarget(summon);
    --        skill.setSkill(ClientFight.SkillClientManager.createFightSkill(fight, FightConst.BUFF_DAMAGE_SKILL,summon));


    for i, _fighter in pairs(ours) do

        ClientFight.EventManager.notifyEventListener(fight, FightEventEnum.ANY_FIGHTER_DIE_AFTER, _fighter.fighterId, summon);
        ClientFight.EventManager.notifyEventListener(fight, FightEventEnum.OUR_FIGHTER_DIE_AFTER, _fighter.fighterId, summon);
    end
    local others = FighterUtils.getOthersBy(summon, true, nil);
    for i, _fighter in pairs(others) do

        ClientFight.EventManager.notifyEventListener(fight, FightEventEnum.ANY_FIGHTER_DIE_AFTER, _fighter.fighterId, summon);
        ClientFight.EventManager.notifyEventListener(fight, FightEventEnum.OTHER_FIGHTER_DIE_AFTER, _fighter.fighterId, summon);
    end
    removeAllBuff(fight, summon);
end


--[[
 * 随机移除一种类型buff
 *
 * @param fight
 * @param fighter
 ]]
function this.removeAllBuff(fight, fighter)
    local buffs = clone(fighter.buffs);
    for k, v in pairs(fighter.permanentBuffs) do
        buffs[k] = v
    end
    if (table.getn(buffs) > 0) then
        for i, buff in pairs(buffs) do

            --SkillRoleMgr.savePathFile(
            --        "[" .. fight.frame .. "][DIE]" .. fighter.fighterId .. "死亡被移除buff" .. buff.modelId);
            ----}
            ClientFight.BuffManager.removeFighterBuff(fight, fighter, buff, true, buff.addParameters);
        end
    end

end

--[[
 * 变更位置
 * @param moved 移动的距离 ==0 表示,用移动前的位置,和移动后的位置,重新计算距离
 * @param changeType 预留
 * @param addReport 是否写入战报通知前端
 ]]
addOverload(this, "changePosition", function(fight, fighter, moved, x, y, changeType, addReport, checkOut)
    return changePosition(fight, fighter, moved, Vector2.New(x, y), changeType, addReport, checkOut, false);

end, "table", "table", "number", "number", "number", "number", "boolean", "boolean")

addOverload(this, "changePosition", function(fight, fighter, moved, x, y, changeType, addReport, checkOut, clearMoveTarget)
    return changePosition(fight, fighter, moved, Vector2.New(x, y), changeType, addReport, checkOut, clearMoveTarget);

end, "table", "table", "number", "number", "number", "number", "boolean", "boolean", "boolean")


--[[
 * 变更位置
 * @param moved 移动的距离 ==0 表示,用移动前的位置,和移动后的位置,重新计算距离
 * @param changeType 预留
 * @param addReport 是否写入战报通知前端
 * @param clear FIXME: 2021/5/31 一些特殊脚本例如瞬移之类的 这个职设为true 用于重新找目标与告知前端结束移动
 *
 ]]
--因为 该方法中 会改变 targetPos的值, 所以不允许外部调用这个方法
addOverload(this, "changePosition", function(fight, fighter, moved, targetPos, changeType, addReport,
                                             checkOut, clear)
    if (clear) then
        fighter.moveTarget = nil;
        fighter.moveDirection = 0;
        fighter.moveAction = nil;
        fighter.movePosition = nil;
    end
    local out = false;
    if (checkOut) then
        out = this.checkOut(targetPos, fighter.shape, Global.FIGHT_INNER_ROUND, false, false);
    end
    local oldPos = Vector2.New(fighter.position.x, fighter.position.y);
    fighter.position.x = targetPos.x;
    fighter.position.y = targetPos.y;

    if (moved == 0) then
        local distance = DistanceUtil.countDistance(fighter.position, oldPos);
        moved = distance;
    end

    if (addReport) then
        local frameInfoCommand = ReportManager.changePointToJsonString(fight, fighter, changeType, nil);
        table.insert(fight.actions, frameInfoCommand);
        FightManager.playActions(frameInfoCommand)
    end
    ClientFight.EventManager.notifyEventListener(fight, FightEventEnum.AFTER_MOVE, fighter.fighterId,
            fighter, moved, oldPos);
    return out;
end, "table", "table", "number", "table", "number", "boolean", "boolean", "boolean")

--[[
 * 是否出界
 *
 * @param fighter
 * @return
 ]]
addOverload(this, "checkOut", function(fighter, round)
    return this.checkOut(fighter.position, fighter.shape, round, false, false);
end, "table", "table")

--[[
 * 是否出界
 * @param ignoreLeft 忽视左边界
 * @param ignoreRight 忽视右边界
 * @return
 ]]
addOverload(this, "checkOut", function(point, shape, round, ignoreLeft, ignoreRight)
    local out = false;
    local width = shape == nil and 0 or shape.width;
    local length = shape == nil and 0 or shape.length;
    --如果超出了左右边界将位置调整会最左或最右
    if (not ignoreRight and point.x + length / 2 > round[2][1]) then
        point.x = round[2][1] - length / 2 - 0.001;
        out = true;
    elseif (not ignoreLeft and point.x - length / 2 < round[1][1]) then
        point.x = round[1][1] + length / 2 + 0.001;
        out = true;
    end
    --如果超出了上下边界将位置调整到最上或最右
    if (point.y + width / 2 > round[1][3]) then
        point.y = round[1][3] - width / 2;
        out = true;
    elseif (point.y - width / 2 < round[2][3]) then
        point.y = round[2][3] + width / 2;
        out = true;
    end

    return out;
end, "table", "table", "table", "boolean", "boolean")

--[[
 * 是否可以使用技能（不包含能量判断，这个用于技能释放中打断）
 *
 * @param fight
 * @param fighter
 * @param skill
 * @return
 ]]
function this.canUseSkill(fight, fighter, skill)
    -- 技能不能使用
    if (FighterStateEnum.is(fighter, FighterStateEnum.CAN_NOT_USE_SKILL)
            and skill.skillBean.f_SkillType ~= SkillTypeEnum.NORMAL_ATTACK) then
        return false;
    elseif (FighterStateEnum.is(fighter, FighterStateEnum.CAN_NOT_NORMAL_ATTACK)
            and skill.skillBean.f_SkillType == SkillTypeEnum.NORMAL_ATTACK) then
        return false;
    end
    return true;
end

--[[
 * 检查战斗结束
 *
 * @param fight
 ]]
function this.checkFinish(fight)
    -- 检查战斗是否结束
    for i = 1, table.getn(fight.teams) do
        local all = true;
        local fightTeam = fight.teams[i];
        local fighters = fightTeam.fighters;
        for i, _fighter in pairs(fighters) do

            -- 召唤物不计入结算
            if (_fighter.summons) then
                goto continue
            end
            if (not _fighter:isDie()) then
                all = false;
                break ;
            end

            :: continue ::
        end
        if (table.getn(fightTeam.alternates) > 0) then
            all = false;
        end

        if (all) then
            fight.finish = bit.bor(fight.finish, bit.lshift(1, i - 1));
            SkillRoleMgr.savePathFile("[" .. fight.frame .. "] 战斗结束");
        end
    end
end

--[[
 * 增加能量
 ]]
addOverload(this, "addEnergy", function(fight, fighter, skillId, skillFrame, energy, reason, notifyEvent)
    if (energy > 0 and fighter.totalSign.signs[FighterSignEnum.NO_ENERGY]) then
        SkillRoleMgr.savePathFile("[" .. fight.frame .. "][EFFECT]Fighter " .. fighter.fighterId .. "禁止增加能量" .. "skill=" .. skillId);
        return 0;
    end
    if (energy == 0) then
    return 0;
    end
    local recover = FighterAttributeManager.getFightAttr(fighter, FighterAttributeEnum.ENERGY);
    energy = math.floor((energy * (Global.TEN_THOUSANDTH + recover) / Global.TEN_THOUSANDTH) + 0.5);

    local fightResult = FightResult.New();
    fightResult.damage = energy;
    fightResult.damageType = SkillDamageTypeEnum.ENERGY;
    if (notifyEvent) then
        ClientFight.EventManager.notifyEventListener(fight, FightEventEnum.CHANGE_ENERGY_BEFORE, fighter.fighterId,
                fighter, skillId, fightResult, reason);
    end

    if (fightResult:getDamage() == 0) then
        return fighter.energy;
    end

    fighter.energy = fighter.energy + fightResult.damage;
    local value = 0;
    if (fighter.energy > fighter.maxEnergy) then
        value = fighter.energy - fighter.maxEnergy;
        fighter.energy = fighter.maxEnergy;
    elseif (fighter.energy < 0) then
        value = fighter.energy;
        fighter.energy = 0;
    end
    if (notifyEvent) then
        ClientFight.EventManager.notifyEventListener(fight, FightEventEnum.CHANGE_ENERGY_AFTER, fighter.fighterId,
                fighter, skillId, fightResult, reason);
    end
    --
    if skillId == nil then
        local a = 1;
    end
    SkillRoleMgr.savePathFile("[" .. fight.frame .. "][EFFECT]Fighter " .. fighter.fighterId .. "能量变动为" .. fighter.energy ..
            " skillId:" .. skillId .. "原因:" .. reason);

    local frameInfoCommand = ReportManager.energyToJsonString(fight, fighter, fighter, skillId, skillFrame, fightResult.damage);
    table.insert(fight.actions, frameInfoCommand);
    FightManager.playActions(frameInfoCommand)
    return value;
end, "table", "table", "number", "number", "number", "number", "boolean")

--[[
 * 增加能量
 ]]
addOverload(this, "addEnergy", function(fight, fighter, skillId, skillFrame, energy, reason)
    return this.addEnergy(fight, fighter, skillId, skillFrame, energy, reason, true);

end, "table", "table", "number", "number", "number", "number")

----[[
-- * 减少能量
-- ]]
--function this.subEnergy(Fight fight, Fighter fighter, int skillId, int skillFrame, long energy) {
--    energy = Math.min(fighter.getEnergy(), energy);
--
--    ClientFight.EventManager.notifyEventListener(fight, FightEventEnum.CHANGE_ENERGY_BEFORE.getId(), fighter.fighterId,
--            fighter, skillId, -energy);
--
--    fighter.setEnergy(fighter.getEnergy() - energy);
--
--    ClientFight.EventManager.notifyEventListener(fight, FightEventEnum.CHANGE_ENERGY_AFTER.getId(), fighter.fighterId,
--            fighter, skillId, -energy);
--
--    LogUtil.info( "[" .. fight.frame .. "][EFFECT]Fighter " .. fighter.fighterId .. "能量减少" .. energy);
--    fight.actions.add(ReportManager.energyToJsonString(fight, fighter, fighter, skillId, skillFrame, -energy));
--}

--[[
 * 获取fighter移动速度
 *
 * @param fighter
 * @return
 ]]
function this.getFighterMoveSpeed(fighter)
    return fighter.heroBean.f_HeroMoveSpeed;
end

--[[
 * 增加被动技能效果
 *
 * @param fighter
 ]]
function this.addPassiveSkillEffect(fight, fighter)
    --这里必须要new 新的list , 因为有些被动效果 会触发英雄/召唤,继承新的被动效果,所以在遍历过程中,可能有新的被动技能加入到getPassiveskills里
    local passiveskills = clone(fighter.passiveskills);
    for i, passiveSkill in pairs(passiveskills) do

        local uuid = passiveSkill.uuid;
        if (uuid ~= 0) then
            goto continue
        end
        fight.skillIds = fight.skillIds + 1;
        uuid = fight.skillIds;

        passiveSkill.uuid = uuid;
        if (passiveSkill.skillBean.f_TriggerType == SkillActionTypeEnum.INIT_MY) then
            if (fight.teams[fighter.teamIndex].initSkills[uuid]) then
                goto continue
            end
            local skill = FightUsingSkill.New();
            skill.skillUniqueId = uuid;
            skill.fight = fight;
            skill.fighter = fighter;
            skill.skill = passiveSkill;
            fight.teams[fighter.teamIndex].initSkills[uuid] = skill;
        elseif (passiveSkill.skillBean.f_TriggerType == SkillActionTypeEnum.INIT_TARGET) then
            if (fight.teams[3 - fighter.teamIndex].initSkills[uuid]) then
                goto continue
            end
            local skill = FightUsingSkill.New();
            skill.skillUniqueId = uuid;
            skill.fight = fight;
            skill.fighter = fighter;
            skill.skill = passiveSkill;
            fight.teams[3 - fighter.teamIndex].initSkills[uuid] = skill;
        elseif (passiveSkill.skillBean.f_TriggerType == SkillActionTypeEnum.PASSIVE) then
            local skill = FightUsingSkill.New();
            skill.skillUniqueId = uuid;
            skill.fight = fight;
            skill.fighter = fighter;
            skill.skill = passiveSkill;
            ClientFight.SkillClientManager.addPassiveSkillEffect(fight, fighter, fighter, skill);
        end

        :: continue ::
    end
end

--[[
 * 增加开场被动技能效果
 ]]
function this.addInitFightPassiveSkillEffect(fight, fighter)
    local team = fight.teams[fighter.teamIndex];
    local usingSkillHashMap = team.initSkills;
    for i, passiveSkill in pairs(usingSkillHashMap) do

        ClientFight.SkillClientManager.addPassiveSkillEffect(fight, passiveSkill.fighter, fighter, passiveSkill);
    end
end



